package utils;

import io.netty.buffer.ByteBuf;
import io.netty.buffer.ByteBufAllocator;
/**
 * 字节工具
 * @author pc
 *
 */
public class ByteUtils {
	
	/**
	 * 写如可变int
	 * @param value
	 * @param msg
	 */
	public static final void writeVariaInt(int value,ByteBuf msg)
	{
		while (true) {
			if ((value & ~0x7F) == 0) {
				msg.writeByte(value);
				return;
			} else {
				msg.writeByte((value & 0x7F) | 0x80);
				value >>>= 7;
			}
		}
	}
	
	/**
	 * 写入可变long
	 * @param value
	 * @param msg
	 */
	public static final void writeVariaLong(long value,ByteBuf msg)
	{
		while (true) {
			if ((value & ~0x7FL) == 0) {
				msg.writeByte((int)value);
				return;
			} else {
				msg.writeByte(((int) value & 0x7F) | 0x80);
				value >>>= 7;
			}
		}
	}
	
	/**
	 * 读取可变int
	 * @param msg
	 * @return
	 */
	public static final int readVariaInt(ByteBuf msg)
	{
		int shift = 0;
		int result = 0;
		while (shift < 32) {
			final byte b = msg.readByte();
			result |= (long) (b & 0x7F) << shift;
			if ((b & 0x80) == 0) {
				return result;
			}
			shift += 7;
		}
		return 0;
	}
	
	/**
	 * 读取可变long
	 * @param msg
	 * @return
	 */
	public static final long readVariaLong(ByteBuf msg)
	{
		int shift = 0;
		long result = 0;
		while (shift < 64) {
			final byte b = msg.readByte();
			result |= (long) (b & 0x7F) << shift;
			if ((b & 0x80) == 0) {
				return result;
			}
			shift += 7;
		}
		return 0;
	}
	
	/**
	 * 读取可变int
	 * read位置没变
	 * @param msg
	 * @return
	 */
	public static final int getVariaInt(int offset,ByteBuf msg)
	{
		int shift = 0;
		int result = 0;
		while (shift < 32) {
			final byte b = msg.getByte(offset++);
			result |= (long) (b & 0x7F) << shift;
			if ((b & 0x80) == 0) {
				return result;
			}
			shift += 7;
		}
		return 0;
	}
	
	
	
	
	
	/**
	 * 读取可变long
	 * read位置没变
	 * @param msg
	 * @return
	 */
	public static final long getVariaLong(int offset,ByteBuf msg)
	{
		int shift = 0;
		long result = 0;
		while (shift < 64) {
			final byte b = msg.getByte(offset++);
			result |= (long) (b & 0x7F) << shift;
			if ((b & 0x80) == 0) {
				return result;
			}
			shift += 7;
		}
		return 0;
	}
	
	
	public static void main(String[] args) {
		ByteBuf bb = ByteBufAllocator.DEFAULT.buffer();
		writeVariaInt(128, bb);
		writeVariaLong(11,bb);
		bb = bb.slice();
//		System.out.println(bb.readableBytes());
		System.out.println(getVariaInt(0,bb));
		System.out.println(getVariaInt(0,bb));
		
		System.out.println(getVariaLong(2,bb));
		
	}
	
	
	
	
	
}
